﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Configuration;

namespace SMS
{
    public partial class FrmSms : Form
    {
        private Stopwatch stw = new Stopwatch(); //计算系统运行时间的类

        public FrmSms()
        {
            InitializeComponent();
        }

        #region 托盘

        private void FrmSms_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Hide();
                this.notifyIcon.Visible = true;
            }
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            this.WindowState = FormWindowState.Minimized;
            e.Cancel = true;
        }

        private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            ShowCtiServer();
        }

        private void showToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowCtiServer();
        }

        private void hideToolStripMenuItem_Click(object sender, EventArgs e)
        {
            HideCtiServer();
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CloseCtiServer();
        }

        private void CloseCtiServer()
        {
            this.notifyIcon.Visible = false;
            this.Close();
            this.Dispose();
            Application.Exit();
        }

        private void HideCtiServer()
        {
            this.Hide();
        }

        private void ShowCtiServer()
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
            this.Activate();
        }

        #endregion

        private void FrmSms_Load(object sender, EventArgs e)
        {
            #region 设备初始化

            int port = Convert.ToInt32(ConfigurationManager.AppSettings["port"]);
            int baud = Convert.ToInt32(ConfigurationManager.AppSettings["baud"]);

            //清空信号进度条
            pbXh.Value = 0;
            //检查OCX是否更新
            SysHelper.CheckOcx();

            //设备初始化
            int nRet = axZogLabSMS.SMSStartup(port, baud);

            if (nRet == 0)
            {
                BLL.Unity.ShowError("设备初始化失败!");
                this.Close();
            }
            else if (nRet == 2)
            {
                BLL.Unity.ShowError("设备已经初始化，不能重复初始化!");
            }

            #endregion

            //隐藏程序至托盘
            this.Hide();
            this.notifyIcon.Visible = true;

            //开始记录程序运行时间 
            stw.Start();
            ShowRunTime();

            //开启计时器
            timer.Start();
        }

        #region 短信处理

        private void axZogLabSMS_SQResponse(object sender, AxZOGLABSMSLib._DZogLabSMSEvents_SQResponseEvent e)
        {
            int nSQVal = e.nSQVal;
            this.labXh.Text = "信号强度：" + nSQVal + "%";
            this.pbXh.Value = nSQVal;
        }

        private void axZogLabSMS_OnReceivedSMS(object sender, AxZOGLABSMSLib._DZogLabSMSEvents_OnReceivedSMSEvent e)
        {
            BLL.SmsBLL bs = new BLL.SmsBLL();
            BLL.DelegateBLL bd = new BLL.DelegateBLL();

            BLL.SmsBLL.SmsType flag = BLL.SmsBLL.SmsType.Ignore;    //接收到短信，保存到数据库的默认类型 
            DateTime receiveTime = DateTime.Now;                    //记录短信接收时间
            string xjbh = "未知";                                   //选举编号

            //获得短信的头
            string SMSHead = bs.SMSResolve(e.strContent);

            switch (SMSHead)
            {
                case BLL.SmsBLL.DELEGATE:   //委托出来，短信格式：WT#被委托人身份证号码或姓名

                    #region  短信委托处理

                    try
                    {
                        DAL.Xm wtr = bs.GetXMByPhone(e.strNumber);  //获取委托人信息

                        if (wtr != null)  //判断委托人是否存在
                        {
                            flag = BLL.SmsBLL.SmsType.Delegate;  //接收短信类型改为委托

                            bd.UpdateReplyFlag(wtr);             //标记选民已回复

                            //获得选举编号
                            xjbh = wtr.xjbh;

                            //判断是否已经委托过
                            DAL.Wtjl wtjl1 = bd.GetWTJLBySfzh(wtr.sfzh);
                            if (wtjl1 == null)
                            {

                                //获得短信“#”后的信息
                                string message = e.strContent.Substring(3);

                                //判断信息是否为有效的省份证号
                                if (bd.CheckIDCard(message))
                                {
                                    //委托业务处理
                                    DAL.Xm bwtr = bd.GetXMBySfzh(message, xjbh);    //根据身份证号和选举编号获取被委托人信息 
                                    if (bwtr != null)
                                    {
                                        if (bwtr.sybwtcs > 0)
                                        {

                                            DateTime now = DateTime.Now;            //获得当前时间
                                            string yzm = bd.GenerateCode();         //生成验证码

                                            using (DAL.DataClassesDataContext dc = new DAL.DataClassesDataContext())
                                            {
                                                DAL.Wtjl wt = new DAL.Wtjl();
                                                wt.jlbh = now.ToString("yyyyMMddHHmmssfff") + yzm;
                                                wt.yzm = yzm;
                                                wt.xjbh = wtr.xjbh;
                                                wt.fssj = now;
                                                wt.wtrsfzh = wtr.sfzh;
                                                wt.wtname = wtr.xmxm;
                                                wt.bwtrsfzh = bwtr.sfzh;
                                                wt.bwtname = bwtr.xmxm;
                                                wt.wtfs = BLL.DelegateBLL.SMS;
                                                wt.flag = BLL.DelegateBLL.SUCCESS;
                                                wt.wtrmobile = e.strNumber;

                                                dc.Wtjl.InsertOnSubmit(wt);

                                                //被委托人剩余被委托次数减一
                                                bd.UpdateSybwtcs(bwtr, bwtr.sybwtcs - 1);

                                                //委托人标记为已经委托
                                                bd.UpdateWtrFlag(wtr, "Y");

                                                dc.SubmitChanges();
                                            }
                                            string reply = string.Format("委托成功！您已于{0}成功委托{1}为您投票,委托验证码为{2}。感谢您使用基层选举委托认证系统短信平台。", now, bwtr.xmxm, yzm);
                                            //axZogLabSMS.SMSSendMessage(reply, e.strNumber);
                                            CutSMS(reply, e.strNumber);

                                            //保存发送短信
                                            bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Reply, reply, e.strNumber, BLL.SmsBLL.SMSCENTERNUMBER);

                                            //被委托人手机号码不为空
                                            if (!String.IsNullOrEmpty(bwtr.sjhm))
                                            {
                                                string reply2 = string.Format("{0}已于{1}成功委托您为其投票,委托验证码为{2}，请您妥善保存此短信。[基层选举委托认证系统短信平台]", wtr.xmxm, now, yzm);
                                                CutSMS(reply2, bwtr.sjhm);

                                                //保存发送短信
                                                bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Reply, reply2, bwtr.sjhm, BLL.SmsBLL.SMSCENTERNUMBER);
                                            }
                                        }
                                        else //被委托人剩余被委托次数为零 
                                        {
                                            string message1 = "委托失败！被委托人剩余被委托次数为零,不能再被委托，请委托其他人。[基层选举委托认证系统短信平台]";
                                            CutSMS(message1, e.strNumber);

                                            //保存发送短信
                                            bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Reply, message1, e.strNumber, BLL.SmsBLL.SMSCENTERNUMBER);
                                        }
                                    }
                                    else //获取不到被委托人信息
                                    {
                                        //委托意向处理
                                        string yzm = bd.GenerateCode();                         //生成验证码
                                        DelegateIntention(wtr, message, e.strNumber, yzm);      //调用委托意向出来方法
                                    }
                                }
                                //判断信息是否为中文汉字，如全为汉字则视为姓名
                                else if (bd.CheckChineseWord(message))
                                {
                                    //委托意向处理
                                    string yzm = bd.GenerateCode();                         //生成验证码
                                    DelegateIntention(wtr, message, e.strNumber, yzm);      //调用委托意向出来方法
                                }
                                else
                                {
                                    string mess = "您发送的内容格式有误，请从新编辑发送。[基层选举委托认证系统短信平台]";
                                    CutSMS(mess, e.strNumber);

                                    //保存发送短信
                                    bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Reply, mess, e.strNumber, BLL.SmsBLL.SMSCENTERNUMBER);
                                }
                            }
                            else
                            {
                                string reply = string.Format("委托失败！您已于{0}成功委托{1}为您投票,委托验证码为{2},不能再次委托！。[基层选举委托认证系统短信平台]。", wtjl1.fssj, wtjl1.bwtname, wtjl1.yzm);
                                CutSMS(reply, e.strNumber);

                                //保存发送短信
                                bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Reply, reply, e.strNumber, BLL.SmsBLL.SMSCENTERNUMBER);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        axZogLabSMS.SMSSendMessage("系统繁忙，请稍后再试！", e.strNumber);

                        //保存发送短信
                        bs.SaveSms("未知", BLL.SmsBLL.SmsType.Erro, "系统繁忙，请稍后再试！" + ex.Message, e.strNumber, BLL.SmsBLL.SMSCENTERNUMBER);
                    }
                    #endregion

                    break;
                case BLL.SmsBLL.CANCEL:     //取消委托，短信格式: QX

                    #region 短信取消委托处理

                    try
                    {
                        DAL.Xm wtr2 = bs.GetXMByPhone(e.strNumber);  //获取委托人信息

                        if (wtr2 != null)  //判断委托人是否存在
                        {
                            bd.UpdateReplyFlag(wtr2);   //标记选民已回复

                            flag = BLL.SmsBLL.SmsType.Cancel; //接收短信类型改为取消操作
                            xjbh = wtr2.xjbh;

                            DAL.Wtjl wtjl2 = bd.GetWTJLBySfzh(wtr2.sfzh);    //获取委托人委托信息 

                            if (wtjl2 != null)
                            {
                                DAL.Xm bwtr = bd.GetXMBySfzh(wtjl2.bwtrsfzh, wtjl2.xjbh);        //获取被委托人信息

                                using (DAL.DataClassesDataContext dc = new DAL.DataClassesDataContext())
                                {

                                    bd.UpdateSybwtcs(bwtr, bwtr.sybwtcs + 1);              //被委托人剩余委托次数加一
                                    bd.UpdateDelegteFlag(wtjl2, BLL.DelegateBLL.FAIL);     //更改委托状态
                                    bd.UpdateWtrFlag(wtr2, "N");                           //更改委托人状态
                                    dc.SubmitChanges();
                                }
                                string qxReply = "取消成功！您已成功取消对" + wtjl2.bwtname + "的委托。[基层选举委托认证系统短信平台]";
                                CutSMS(qxReply, e.strNumber);

                                //保存发送短信
                                bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Reply, qxReply, e.strNumber, BLL.SmsBLL.SMSCENTERNUMBER);

                                //被委托人手机号码不为空
                                if (!String.IsNullOrEmpty(bwtr.sjhm))
                                {
                                    string qxReply_b = wtjl2.wtname + "已取消对您的委托。[基层选举委托认证系统短信平台]";
                                    CutSMS(qxReply_b, bwtr.sjhm);

                                    //保存发送短信
                                    bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Reply, qxReply_b, bwtr.sjhm, BLL.SmsBLL.SMSCENTERNUMBER);
                                }
                            }
                            else
                            {
                                string nullReply = "您暂无委托记录，回复'WT#被委托人身份证号或姓名'进行委托。[基层选举委托认证系统短信平台]";
                                CutSMS(nullReply, e.strNumber);

                                //保存发送短信
                                bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Reply, nullReply, e.strNumber, BLL.SmsBLL.SMSCENTERNUMBER);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        axZogLabSMS.SMSSendMessage("系统繁忙，请稍后再试！", e.strNumber);

                        //保存发送短信
                        bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Erro, "系统繁忙，请稍后再试！" + ex.Message, e.strNumber, BLL.SmsBLL.SMSCENTERNUMBER);
                    }

                    #endregion

                    break;
                case BLL.SmsBLL.QUERY:      //查询委托，短信格式：CX#委托人身份证号

                    #region 短信委托查询处理

                    try
                    {
                        if (bs.CheckPhone(e.strNumber))  //判断短信来源号码是否为登记选民
                        {

                            flag = BLL.SmsBLL.SmsType.Query;      //接收短信类型改为查询                      

                            DAL.Wtjl wtjl3 = bd.GetWTJLBySfzh(e.strContent.Substring(3));    //获取委托信息
                            DAL.Xm cxr = bs.GetXMByPhone(e.strNumber);                       //获取查询人信息

                            xjbh = cxr.xjbh;

                            bd.UpdateReplyFlag(cxr);   //标记选民已回复

                            if (wtjl3 != null)
                            {


                                if (cxr.sfzh == wtjl3.wtrsfzh) //查询人为委托人
                                {
                                    string reply = string.Format("查询成功!您已于{0}成功委托{1}为您投票,委托验证码为{2}。[基层选举委托认证系统短信平台]。", wtjl3.fssj, wtjl3.bwtname, wtjl3.yzm);
                                    CutSMS(reply, e.strNumber);

                                    //保存发送短信
                                    bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Reply, reply, e.strNumber, BLL.SmsBLL.SMSCENTERNUMBER);
                                }
                                else if (cxr.sfzh == wtjl3.bwtrsfzh) //查询人为被委托人
                                {
                                    string reply = string.Format("查询成功!{0}已于{1}成功委托您为其投票,委托验证码为{2}，请您妥善保存此短信。[基层选举委托认证系统短信平台]。", wtjl3.wtname, wtjl3.fssj, wtjl3.yzm);
                                    CutSMS(reply, e.strNumber);

                                    //保存发送短信
                                    bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Reply, reply, e.strNumber, BLL.SmsBLL.SMSCENTERNUMBER);
                                }
                            }
                            else
                            {
                                string reply = "查询失败！未能查询到委托记录，请检测发送信息是否有误。[基层选举委托认证系统短信平台]";
                                CutSMS(reply, e.strNumber);

                                //保存发送短信
                                bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Reply, reply, e.strNumber, BLL.SmsBLL.SMSCENTERNUMBER);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        axZogLabSMS.SMSSendMessage("系统繁忙，请稍后再试！", e.strNumber);

                        //保存发送短信
                        bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Erro, "系统繁忙，请稍后再试！" + ex.Message, e.strNumber, BLL.SmsBLL.SMSCENTERNUMBER);
                    }

                    #endregion

                    break;
                default:

                    flag = BLL.SmsBLL.SmsType.Erro;  //接收短信类型改为错误

                    string mes = "您发送的内容格式有误，1.委托操作请发送WT#被委托人身份证号或姓名2.取消委托请发送QX3.查询委托请发送CX#委托人身份证号[基层选举委托认证系统短信平台]";
                    CutSMS(mes, e.strNumber);

                    //保存发送短信
                    bs.SaveSms(xjbh, BLL.SmsBLL.SmsType.Notice, mes, e.strNumber, BLL.SmsBLL.SMSCENTERNUMBER);
                    break;
            }

            //保存接收短信
            bs.SaveSms(xjbh, flag, e.strContent, BLL.SmsBLL.SMSCENTERNUMBER, e.strNumber, receiveTime);
        }

        #endregion

        private void timer_Tick(object sender, EventArgs e)
        {
            ShowRunTime();
            axZogLabSMS.QueryNewMsg();

            int nowHour = DateTime.Now.Hour;


            //从早上九点开始到下午6点
            if (9 < nowHour && nowHour < 18)
            {
                //每十分钟一次检索选举，发送通知短信
                if (DateTime.Now.Minute % 10 == 0 && DateTime.Now.Second == 0)
                {
                    Notice();
                }
            }
        }

        /// <summary>
        /// 显示系统已运行时间
        /// </summary>
        void ShowRunTime()
        {
            labTime.Text = "程序已运行时间:" + stw.Elapsed.Minutes.ToString() + "分钟";
        }

        /// <summary>
        /// 发送通知
        /// </summary>
        void Notice()
        {
            try
            {
                BLL.DelegateBLL bd = new BLL.DelegateBLL();
                BLL.SmsBLL bs = new BLL.SmsBLL();

                DAL.Xjdj xj = bd.GetXJ(); //获取最近委托信息 
                if (xj != null)
                {
                    using (DAL.DataClassesDataContext dc = new DAL.DataClassesDataContext())
                    {
                        var xms = dc.Xm.Where(x => x.xjbh == xj.xjbh && x.sjhm != null && x.sjhm != "");  //获取该选举有手机号码的选民

                        //遍历选民发送通知短信
                        foreach (var item in xms)
                        {
                            string mes = "尊敬的选民，您好！您现在可以通过基层选举认证系统进行选举委托。系统地址为" + "www.xxxx.com" + @"或直接发送短信进行委托：1.委托操作请发送WT#被委托人身份证号或姓名2.取消委托请发送QX3.查询委托请发送CX#委托人身份证号[基层选举委托认证系统短信平台]";
                            CutSMS(mes, item.sjhm);

                            //保存发送短信
                            bs.SaveSms(item.xjbh, BLL.SmsBLL.SmsType.Notice, mes, item.sjhm, BLL.SmsBLL.SMSCENTERNUMBER);

                            //选民标记为已经通知
                            item.send = "Y";
                        }
                        //更新选举状态为已通知
                        bd.UpdateXjFlag(xj);
                        dc.SubmitChanges();
                    }
                }
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 委托意向处理
        /// </summary>
        /// <param name="wtr">委托人</param>
        /// <param name="bwtr">被委托人信息</param>
        /// <param name="phone">委托人手机</param>
        /// <param name="yzm">验证码</param>
        void DelegateIntention(DAL.Xm wtr, string bwtr, string phone, string yzm)
        {
            BLL.SmsBLL bs = new BLL.SmsBLL();

            try
            {
                DateTime now = DateTime.Now;            //获得当前时间

                using (DAL.DataClassesDataContext dc = new DAL.DataClassesDataContext())
                {
                    DAL.Wtjl wt = new DAL.Wtjl();
                    wt.jlbh = now.ToString("yyyyMMddHHmmssfff") + yzm;
                    wt.yzm = yzm;
                    wt.xjbh = wtr.xjbh;
                    wt.fssj = now;
                    wt.wtrsfzh = wtr.sfzh;
                    wt.wtname = wtr.xmxm;
                    wt.bwtrsfzh = bwtr;
                    wt.bwtname = bwtr;
                    wt.wtfs = BLL.DelegateBLL.SMS;
                    wt.flag = BLL.DelegateBLL.UNHANDLED;
                    wt.wtrmobile = phone;

                    dc.Wtjl.InsertOnSubmit(wt);
                    dc.SubmitChanges();
                }
                string message = "您的委托意向已记录，工作人员会尽快和您取得联系，请您留意，感谢您使用基层选举委托认证系统短信平台。";
                CutSMS(message, phone);

                //保存发送短信
                bs.SaveSms(wtr.xjbh, BLL.SmsBLL.SmsType.Reply, message, phone, BLL.SmsBLL.SMSCENTERNUMBER);
            }
            catch (Exception e)
            {
                axZogLabSMS.SMSSendMessage("系统繁忙，请稍后再试！", phone);

                //保存发送短信
                bs.SaveSms(wtr.xjbh, BLL.SmsBLL.SmsType.Erro, "系统繁忙，请稍后再试！" + e.Message, phone, BLL.SmsBLL.SMSCENTERNUMBER);
            }
        }

        /// <summary>
        /// 将过长短信截成多条发送
        /// </summary>
        /// <param name="str">短信内容</param>
        /// <param name="PhoneNum">手机号码</param>
        void CutSMS(string str, string PhoneNum)
        {
            string s;
            int len = 65; //短信允许最大长度
            int cs = (int)Math.Ceiling(str.Length * 1.0 / len);
            int jsq = 0;
            for (int i = 0; i < str.Length; i++)
            {
                int r = i % len;
                int last = (str.Length / len) * len;
                if (i != 0 && i <= last)
                {
                    if (r == 0)
                    {
                        jsq++;
                        s = str.Substring(i - len, len);
                        axZogLabSMS.SMSSendMessage("(" + jsq + @"/" + cs + ")" + s, PhoneNum);
                        //MessageBox.Show("(" + jsq + @"/" + cs + ")" + s + "to:" + PhoneNum);
                    }
                }
                else if (i > last)
                {
                    s = str.Substring(i - 1);
                    axZogLabSMS.SMSSendMessage("(" + cs + @"/" + cs + ")" + s, PhoneNum);
                    //MessageBox.Show("(" + cs + @"/" + cs + ")" + s + "to:" + PhoneNum);
                    return;
                }
            }
        }

        private void axZogLabSMS_SendResponse(object sender, AxZOGLABSMSLib._DZogLabSMSEvents_SendResponseEvent e)
        {
            //int nResponse = e.nAns;
            //if (nResponse == 0)
            //{
            //    MessageBox.Show("发送失败!");
            //}
            //else if (nResponse == 1)
            //{
            //    MessageBox.Show("发送成功!");
            //}
            //else if (nResponse == 2)
            //{
            //    MessageBox.Show("发送失败, 内容为空!");
            //}
            //else if (nResponse == 3)
            //{
            //    MessageBox.Show("发送失败, 号码错误!");
            //}
        }
    }
}
